﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

class ATM
{
    public static void WithdrawMoney(int cardId, string cardNumber, string pin, decimal money)
    {
        string connectionString = @"Server=.\SQLEXPRESS;Database=ATM;Integrated security=true";
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
        using (conn)
        {
            SqlTransaction trans = conn.BeginTransaction(IsolationLevel.Serializable);
            SqlCommand command = new SqlCommand();
            command.Transaction = trans;
            command.Connection = conn;
            command.Parameters.Add(new SqlParameter("@CardId", cardId));
            command.CommandText = "SELECT CardNumber, CardPin, CardCash FROM CardAccounts WHERE Id = @CardId";
            SqlDataReader reader = command.ExecuteReader();
            if (!reader.HasRows)
            {
                Console.WriteLine("Card is invalid!");
                return;
            }
            reader.Read();
            string cardNum = (string)reader["CardNumber"];
            string cardPin = (string)reader["CardPin"];
            decimal CardCash = (decimal)reader["CardCash"];
            if (cardNum.Equals(cardNumber) && cardPin.Equals(pin))
            {
                reader.Close();
                command.Parameters.Clear();
                command.Parameters.Add(new SqlParameter("@money", CardCash - money));
                command.Parameters.Add(new SqlParameter("@CardId", cardId));
                command.CommandText = "UPDATE CardAccounts SET CardCash = @money WHERE Id = @CardId";
                command.ExecuteNonQuery();
                reader.Close();
                command.CommandText = "SELECT CardCash FROM CardAccounts WHERE Id = @CardId";
                reader = command.ExecuteReader();
                reader.Read();
                decimal ballance = (decimal)reader["CardCash"];
                if (ballance >= 0)
                {
                    reader.Close();
                    try
                    {
                        SqlCommand commandLog = new SqlCommand();
                        commandLog.Connection = conn;
                        commandLog.CommandText = "INSERT INTO AccountTransactions (CardNumber, TransactionDate, Ammount) values (@CardNumber, @TransactionDate, @Ammount)";
                        commandLog.Parameters.Add(new SqlParameter("@CardNumber", cardNumber));
                        commandLog.Parameters.Add(new SqlParameter("@TransactionDate", DateTime.Now));
                        commandLog.Parameters.Add(new SqlParameter("@Ammount", money));
                        commandLog.Transaction = trans;
                        commandLog.ExecuteNonQuery();
                    }
                    catch (SqlException e)
                    {
                        Console.WriteLine("Exception occured: {0}", e.Message);
                        Console.WriteLine("AAAAAAAAAAAAAAAAAAAAAAAAAAA");
                        trans.Rollback();
                    }

                    trans.Commit();
                    Console.WriteLine("Success!");
                }
                else
                {
                    reader.Close();
                    trans.Rollback();
                    Console.WriteLine("Not enough money!");
                }
            }
            else
            {
                Console.WriteLine("Card number and PIN don't match");
                return;
            }
        }
    }

    public static void RetrieveTransactions(string card, string pin)
    {
        SqlConnection connection = new SqlConnection(@"Server=.\SQLEXPRESS;Database=ATM;Integrated security=true");
        connection.Open();
        using (connection)
        {
            SqlCommand command = new SqlCommand("SELECT CardPin FROM CardAccounts WHERE CardNumber = @CardNumber", connection);
            command.Parameters.Add(new SqlParameter("@CardNumber", card));
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                reader.Read();
                string currentPin = (string)reader["CardPin"];
                if (currentPin.Equals(pin))
                {
                    reader.Close();
                    command.CommandText = "SELECT * FROM AccountTransactions WHERE CardNumber = @CardNumber ORDER BY TransactionDate";
                    reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        Console.WriteLine("On {0} - {1:C} were withdrawed.", reader["TransactionDate"], reader["Ammount"]);
                    }
                }
            }
        }
    }

    static void Main()
    {
        //WithdrawMoney(1, "CARD111111", "2283", 50);
        RetrieveTransactions("Card111111", "2283");
    }
}
